package com.atguigu.szdz.dcsyl.controller;

import com.atguigu.szdz.dcsyl.common.utils.R;
import com.atguigu.szdz.dcsyl.service.KxylService;
import com.atguigu.szdz.dcsyl.utils.MapperUtils;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/kxyl")
public class EatonYljsController {
    @Autowired
    private ApplicationContext context;
    @Autowired
    private MapperUtils mapperUtils;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private PlatformTransactionManager transactionManager;
    @Autowired
    private KxylService kxylService;
//    @Autowired
//    private KxylService kxylService;

    @PostMapping("/aaa")
    public String aaa() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        // 使用反射创建对象
        Class<?> clazz = Class.forName("com.atguigu.szdz.dcsyl.service.impl.KxylServiceImpl");
        Constructor<?> constructor = clazz.getConstructor();
        Object instance = constructor.newInstance();

        Method method = clazz.getMethod("aaa");
        TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);

        transactionTemplate.execute(status -> {
            try {
                return method.invoke(instance);
            } catch (IllegalAccessException | InvocationTargetException e) {
                status.setRollbackOnly();
                throw new RuntimeException(e);
            }
        });

        String json = "{\"code\":0,\"message\":\"操作处理成功\",\"data\":{\"total\":37,\"list\":[{\"well_name\":\"A1\",\"depth\":1110,\"lithology\":0.29,\"sound_waves\":0.29,\"density\":0.72,\"well_road\":0.16,\"natural_gamma\":1.36,\"natural_potential\":0.92,\"deep_resistivity\":0.67}" +
                ",{\"well_name\":\"A1\",\"depth\":1111,\"lithology\":0.30,\"sound_waves\":0.30,\"density\":0.73,\"well_road\":0.17,\"natural_gamma\":1.37,\"natural_potential\":0.93,\"deep_resistivity\":0.68}" +
                ",{\"well_name\":\"A1\",\"depth\":1112,\"lithology\":0.31,\"sound_waves\":0.31,\"density\":0.74,\"well_road\":0.18,\"natural_gamma\":1.38,\"natural_potential\":0.94,\"deep_resistivity\":0.69}" +
                ",{\"well_name\":\"A1\",\"depth\":1113,\"lithology\":0.32,\"sound_waves\":0.32,\"density\":0.75,\"well_road\":0.19,\"natural_gamma\":1.39,\"natural_potential\":0.95,\"deep_resistivity\":0.70}" +
                ",{\"well_name\":\"A1\",\"depth\":1114,\"lithology\":0.33,\"sound_waves\":0.33,\"density\":0.76,\"well_road\":0.20,\"natural_gamma\":1.40,\"natural_potential\":0.96,\"deep_resistivity\":0.71}" +
                ",{\"well_name\":\"A1\",\"depth\":1115,\"lithology\":0.34,\"sound_waves\":0.34,\"density\":0.77,\"well_road\":0.21,\"natural_gamma\":1.41,\"natural_potential\":0.97,\"deep_resistivity\":0.72}" +
                ",{\"well_name\":\"A1\",\"depth\":1116,\"lithology\":0.35,\"sound_waves\":0.35,\"density\":0.78,\"well_road\":0.22,\"natural_gamma\":1.42,\"natural_potential\":0.98,\"deep_resistivity\":0.73}" +
                ",{\"well_name\":\"A1\",\"depth\":1117,\"lithology\":0.36,\"sound_waves\":0.36,\"density\":0.79,\"well_road\":0.23,\"natural_gamma\":1.43,\"natural_potential\":0.99,\"deep_resistivity\":0.74}" +
                ",{\"well_name\":\"A1\",\"depth\":1118,\"lithology\":0.37,\"sound_waves\":0.37,\"density\":0.80,\"well_road\":0.24,\"natural_gamma\":1.44,\"natural_potential\":1.00,\"deep_resistivity\":0.75}" +
                ",{\"well_name\":\"A1\",\"depth\":1119,\"lithology\":0.38,\"sound_waves\":0.38,\"density\":0.81,\"well_road\":0.25,\"natural_gamma\":1.45,\"natural_potential\":1.01,\"deep_resistivity\":0.76}" +
                ",{\"well_name\":\"A1\",\"depth\":1120,\"lithology\":0.39,\"sound_waves\":0.39,\"density\":0.82,\"well_road\":0.26,\"natural_gamma\":1.46,\"natural_potential\":1.02,\"deep_resistivity\":0.77}" +
                ",{\"well_name\":\"A1\",\"depth\":1121,\"lithology\":0.40,\"sound_waves\":0.40,\"density\":0.83,\"well_road\":0.27,\"natural_gamma\":1.47,\"natural_potential\":1.03,\"deep_resistivity\":0.78}]}}";
        return json;
    }


    @Operation(summary = "获取孔隙压力echart图表数据")
    @PostMapping("/getKxylecharsList")
    public R getKxylecharsList(@RequestBody Map<String, Object> map) {
        //传过来的参数
        Integer well_id = (Integer) map.get("well_id");
        Double HNG = Double.parseDouble(map.get("HNG").toString());
        Double n = Double.parseDouble(map.get("n").toString());
        Double Vp = Double.parseDouble(map.get("Vp").toString());
        Double Vs = Double.parseDouble(map.get("Vs").toString());
        Double h_rect = Double.parseDouble(map.get("h_rect").toString());
        Double H_rect = Double.parseDouble(map.get("H_rect").toString());
        Double UCS = Double.parseDouble(map.get("UCS").toString());
        Double o = Double.parseDouble(map.get("o").toString());

        //从数据库查询数据
        String sql = "select * from dc_kxjc where well_id = " + well_id;
        List<Map<String, Object>> kxylList = kxylService.getKxylcharsList(sql);
        List<Map<String, Object>> kxylecharsList = new ArrayList<>();
        for (Map<String, Object> kxyl : kxylList) {
            Map<String, Object> kxylechar = new HashMap<>();
            Double depth = (Double) kxyl.get("depth");
            Double obg = (Double) kxyl.get("obg");
            Double dcn = (Double) kxyl.get("dcn");
            Double dc = (Double) kxyl.get("dc");

            //计算孔隙压力pp
            Double pp = obg - (obg - HNG) * (Math.pow(dc / dcn, n));

            //计算泊松比
            Double V = (0.5 * Math.pow(Vp / Vs, 2) - 1) / (Math.pow(Vp / Vs, 2) - 1);
            //计算破裂压力
            Double pf = (V / (1 - V)) * (obg - pp) + pp;

            //计算上覆岩层压力
            Double Sv = obg * depth;
            //计算最大水平主应力
            Double H = (V / (1 - V)) * (Sv - pp) + pp + H_rect;
            //计算最小水平主应力
            Double h = (V / (1 - V)) * (Sv - pp) + pp + h_rect;
            //计算系数q
            Double q = (1 + Math.sin(Math.toRadians(o))) / (1 - Math.sin(Math.toRadians(o)));
            //计算坍塌压力
            Double pc = ((3 * h - H - 2 * pp) - UCS) / (1 + q);

            double lower = pc + 0.1;
            double upper = pf - 0.1;


            kxylechar.put("pp", pp);
            kxylechar.put("pf", pf);
            kxylechar.put("pc", pc);
            kxylechar.put("lower", lower);
            kxylechar.put("upper", upper);
            kxylechar.put("depth", depth);

            System.out.println("测试测试测试测试数据" + kxylechar);
            kxylecharsList.add(kxylechar);
        }
        return R.ok().put("list", kxylList);
    }

    @Operation(summary = "获取孔隙压力echart图表数据(归一化)")
    @PostMapping("/bbb")
    public R bbb(@RequestBody Map<String, Object> map) {
        //传过来的参数
        Integer well_id = (Integer) map.get("well_id");
        String sql = "select * from dc_yldata order by id asc";
        List<Map<String, Object>> kxylList = kxylService.getKxylcharsList(sql);
        List<Map<String, Object>> kxylecharsList = new ArrayList<>();
        //找出最大值最小值
        // 先收集所有有效Double类型的dt值
        List<Double> validDtList = kxylList.stream()
                .map(map1 -> {
                    Object dtValue = map1.get("dt");
                    return (dtValue instanceof Double) ? (Double) dtValue : null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        // 分别求最大、最小值
        Double maxDt = validDtList.stream()
                .max(Comparator.comparingDouble(Double::doubleValue))
                .orElse(null); // 无有效数据则返回null

        Double minDt = validDtList.stream()
                .min(Comparator.comparingDouble(Double::doubleValue))
                .orElse(null);
        //收集所有的obg数据
        List<Double> validObgList = kxylList.stream()
                .map(map2 -> {
                    Object obgValue = map2.get("obg");
                    return (obgValue instanceof Double) ? (Double) obgValue : null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        //分别求最大、最小值
        Double maxObg = validObgList.stream()
                .max(Comparator.comparingDouble(Double::doubleValue))
                .orElse(null); // 无有效数据则返回null

        Double minObg = validObgList.stream()
                .min(Comparator.comparingDouble(Double::doubleValue))
                .orElse(null);
        //收集所有的pp数据
        List<Double> validPpList = kxylList.stream()
                .map(map3 -> {
                    Object ppValue = map3.get("pp");
                    return (ppValue instanceof Double) ? (Double) ppValue : null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        //分别求最大、最小值
        Double maxPp = validPpList.stream()
                .max(Comparator.comparingDouble(Double::doubleValue))
                .orElse(null); // 无有效数据则返回null

        Double minPp = validPpList.stream()
                .min(Comparator.comparingDouble(Double::doubleValue))
                .orElse(null);
        //收集所有的pf数据
        List<Double> validPfList = kxylList.stream()
                .map(map4 -> {
                    Object pfValue = map4.get("pf");
                    return (pfValue instanceof Double) ? (Double) pfValue : null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        //分别求最大、最小值
        Double maxPf = validPfList.stream()
                .max(Comparator.comparingDouble(Double::doubleValue))
                .orElse(null); // 无有效数据则返回null

        Double minPf = validPfList.stream()
                .min(Comparator.comparingDouble(Double::doubleValue))
                .orElse(null);

        Double maxPc = maxPp + maxPf - 12;
        Double minPc = minPp + minPf - 12;
        for (Map<String, Object> kxyl : kxylList) {
            Map<String, Object> kxylechar = new HashMap<>();
            //获取id
            Integer id = (Integer) kxyl.get("id");
            Double depth = (Double) kxyl.get("depth");
            Double pp = (Double) kxyl.get("pp");
            Double pf = (Double) kxyl.get("pf");
            Double dt = (Double) kxyl.get("dt");
            Double obg = (Double) kxyl.get("obg");
            //归一化处理dt
            Double dtNormalized = (dt - minDt) / (maxDt - minDt);
            //归一化处理obg
            Double obgNormalized = (obg - minObg) / (maxObg - minObg);
            //归一化处理pp
            Double ppNormalized = (pp - minPp) / (maxPp - minPp);
            //归一化处理pf
            Double pfNormalized = (pf - minPf) / (maxPf - minPf);
            Double pc = pp + pf - 12;
            Double pcNormalized = (pc - minPc) / (maxPc - minPc);
            double lower = ppNormalized + 0.1;
            double upper = pfNormalized - 0.1;
            kxylechar.put("pp", ppNormalized);
            kxylechar.put("pf", pfNormalized);
            kxylechar.put("pc", pcNormalized);
            kxylechar.put("dt", dtNormalized);
            kxylechar.put("obg", obgNormalized);
            kxylechar.put("lower", lower);
            kxylechar.put("upper", upper);
            kxylechar.put("depth", depth);
            kxylechar.put("id", id);
            kxylecharsList.add(kxylechar);
        }
        return R.ok().put("list", kxylecharsList);
    }

    @Operation(summary = "获取孔隙压力echart图表数据(未归一化)")
    @PostMapping("/ccc")
    public R ccc(@RequestBody Map<String, Object> map) {
        //传过来的参数
        Integer well_id = (Integer) map.get("well_id");
        String sql = "select * from dc_yldata order by id asc";
        List<Map<String, Object>> kxylList = kxylService.getKxylcharsList(sql);
        List<Map<String, Object>> kxylecharsList = new ArrayList<>();
        for (Map<String, Object> kxyl : kxylList) {
            Map<String, Object> kxylechar = new HashMap<>();
            //获取id
            Integer id = (Integer) kxyl.get("id");
            Double depth = (Double) kxyl.get("depth");
            Double pp = (Double) kxyl.get("pp");
            Double pf = (Double) kxyl.get("pf");
            Double dt = (Double) kxyl.get("dt");
            Double obg = (Double) kxyl.get("obg");
            Double pc = pp + pf - 12;
            double lower = pp + 0.1;
            double upper = pf - 0.1;
            kxylechar.put("pp", pp);
            kxylechar.put("pf", pf);
            kxylechar.put("pc", pc);
            kxylechar.put("dt", dt);
            kxylechar.put("obg", obg);
            kxylechar.put("lower", lower);
            kxylechar.put("upper", upper);
            kxylechar.put("depth", depth);
            kxylechar.put("id", id);
            kxylecharsList.add(kxylechar);
        }
        return R.ok().put("list", kxylecharsList);
    }


    @Operation(summary = "返回最开始显示的数据(nhg,ong,dc)")
    @PostMapping("/ddd")
    public R ddd(@RequestBody Map<String, Object> map) {
        //传过来的参数
        Integer well_id = (Integer) map.get("well_id");
        //Eaton指数
        Double n = Double.parseDouble(map.get("n").toString());
        //纵波速度
        Double Vp = Double.parseDouble(map.get("Vp").toString());
        //横波速度
        Double Vs = Double.parseDouble(map.get("Vs").toString());
        //构造应力附项
        Double h_rect = map.get("h_rect") != null ? Double.parseDouble(map.get("h_rect").toString()) : 0.0;
        //构造应力附项
        Double H_rect = map.get("H_rect") != null ? Double.parseDouble(map.get("H_rect").toString()) : 0.0;
        //单轴抗压强度
        Double UCS = Double.parseDouble(map.get("UCS").toString());
        //内摩擦角
        Double o = Double.parseDouble(map.get("o").toString());
        //从数据库查询数据
        String sql = "select * from \"dc_ylDataDc\" where well_id = " + well_id + " order by depth asc";
        List<Map<String, Object>> ylList = kxylService.getKxylcharsList(sql);
        List<Map<String, Object>> kxylecharsList = new ArrayList<>();
        for (Map<String, Object> yl : ylList) {
            Map<String, Object> kxylechar = new HashMap<>();
            //获取id
            Integer id = (Integer) yl.get("id");
            Double depth = (Double) yl.get("depth");
            Double dc = (Double) yl.get("dc");
            Double nhg = (Double) yl.get("nhg");
            Double obg = (Double) yl.get("obg");
            kxylechar.put("obg", obg);
            kxylechar.put("depth", depth);
            kxylechar.put("dc", dc);
            kxylechar.put("nhg", nhg);
            kxylechar.put("id", id);
            kxylechar.put("pp", 0.0);
            kxylechar.put("pf", 0.0);
            kxylechar.put("pc", 0.0);
            kxylecharsList.add(kxylechar);
        }
        return R.ok().put("list", kxylecharsList);
    }

    @Operation(summary = "返回计算的压力数据(默认没有趋势线的时候)")
    @PostMapping("/eee")
    public R eee(@RequestBody Map<String, Object> map) {
        //传过来的参数
        Integer well_id = (Integer) map.get("well_id");
        //Eaton指数
        Double n = Double.parseDouble(map.get("n").toString());
        //纵波速度
        Double Vp = Double.parseDouble(map.get("Vp").toString());
        //横波速度
        Double Vs = Double.parseDouble(map.get("Vs").toString());
        //构造应力附项
        Double h_rect = map.get("h_rect") != null ? Double.parseDouble(map.get("h_rect").toString()) : 0.0;
        //构造应力附项
        Double H_rect = map.get("H_rect") != null ? Double.parseDouble(map.get("H_rect").toString()) : 0.0;
        //单轴抗压强度
        Double UCS = Double.parseDouble(map.get("UCS").toString());
        //内摩擦角
        Double o = Double.parseDouble(map.get("o").toString());
        //斜率
        Double k = map.get("k") != null ? Double.parseDouble(map.get("k").toString()) : 0.0;
        //截距
        Double b = map.get("b") != null ? Double.parseDouble(map.get("b").toString()) : 0.0;
        //从数据库查询数据
        String sql = "select * from \"dc_ylDataDc\" where well_id = " + well_id + " order by depth asc";
        List<Map<String, Object>> ylList = kxylService.getKxylcharsList(sql);
        List<Map<String, Object>> kxylecharsList = new ArrayList<>();
        for (Map<String, Object> yl : ylList) {
            Map<String, Object> kxylechar = new HashMap<>();
            //获取id
            Integer id = (Integer) yl.get("id");
            Double depth = (Double) yl.get("depth");
            Double dc = (Double) yl.get("dc");
            Double nhg = (Double) yl.get("nhg");
            Double obg = (Double) yl.get("obg");
            Double dcn;
            if (k != 0.0) {
                dcn = (depth - b) / k;
            } else {
                dcn = Math.exp(0.0004158 * depth - 1.28100587);
            }
            Double pp = obg - (obg - nhg) * Math.pow((dc / dcn), n);

            //计算泊松比
            Double v = (0.5 * (Vp / Vs) * (Vp / Vs) - 1) / ((Vp / Vs) * (Vp / Vs) - 1);
            Double pf = (v / (1 - v)) * (obg - pp) + pp;
            kxylechar.put("obg", obg);
            kxylechar.put("depth", depth);
            kxylechar.put("dc", dc);
            kxylechar.put("nhg", nhg);
            kxylechar.put("id", id);
            kxylechar.put("pp", pp);
            kxylechar.put("pf", (Double) yl.get("pp_dc") + 0.1);
            kxylechar.put("pc", (Double) yl.get("pp_dc") - 0.2);
            kxylecharsList.add(kxylechar);
        }
        //把计算结果批量插入到数据库



        //返回结果
        return R.ok().put("list", kxylecharsList);
    }

    @Operation(summary = "获取孔隙压力echart图表数据(归一化)")
    @PostMapping("/fff")
    public R fff(@RequestBody Map<String, Object> map) {
        //传过来的参数
        Integer well_id = (Integer) map.get("well_id");
        String sql = "select * from \"dc_ylDataDc\" where well_id = " + well_id + " order by id asc";
        List<Map<String, Object>> kxylList = kxylService.getKxylcharsList(sql);
        List<Map<String, Object>> kxylecharsList = new ArrayList<>();
        //收集所有的pp数据
        List<Double> validPpList = kxylList.stream()
                .map(map3 -> {
                    Object ppValue = map3.get("pp_dc");
                    return (ppValue instanceof Double) ? (Double) ppValue : null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        //分别求最大、最小值
        Double maxPp = validPpList.stream()
                .max(Comparator.comparingDouble(Double::doubleValue))
                .orElse(null); // 无有效数据则返回null

        Double minPp = validPpList.stream()
                .min(Comparator.comparingDouble(Double::doubleValue))
                .orElse(null);


        for (Map<String, Object> kxyl : kxylList) {
            Map<String, Object> kxylechar = new HashMap<>();
            //获取id
            Integer id = (Integer) kxyl.get("id");
            Double depth = (Double) kxyl.get("depth");
            Double pp = (Double) kxyl.get("pp_dc");
            Double nhg = (Double) kxyl.get("nhg");
            Double dc = (Double) kxyl.get("dc");
            Double obg = (Double) kxyl.get("obg");
            //归一化处理pp
            Double ppNormalized = (pp - minPp) / (maxPp - minPp);
            kxylechar.put("pp", ppNormalized);
            kxylechar.put("pf", ppNormalized+0.1);
            kxylechar.put("pc", ppNormalized-0.2);
            kxylechar.put("nhg", nhg);
            kxylechar.put("dc", dc);
            kxylechar.put("obg", obg);
            kxylechar.put("depth", depth);
            kxylechar.put("id", id);
            kxylecharsList.add(kxylechar);
        }
        return R.ok().put("list", kxylecharsList);
    }

    /**
     * 根据Id修改对应压力数据
     *
     * @param map
     * @return
     */
    @Operation(summary = "根据Id修改对应压力数据")
    @PostMapping("/updateById")
    public R updateById(@RequestBody Map<String, Object> map) {
        //获取id
        Integer id = (Integer) map.get("id");
        //获取字段
        String field = (String) map.get("field");
        //获取值
        Double value = (Double) map.get("value");
        //编写sql语句
        String sql = "update dc_yldata set " + field + "=" + value + " where id = " + id;
        mapperUtils.updataBySql(sql);
        return R.ok();
    }
}
